package com.wichell.framework.wechat.controller;

import java.io.IOException;
import java.text.MessageFormat;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

import com.wichell.framework.controller.BaseController;
import com.wichell.framework.wechat.bo.response.WechatOauth2AccessToken;
import com.wichell.framework.wechat.service.WechatRequestService;
import com.wichell.framework.wechat.util.SignUtils;

@Controller
@RequestMapping(value = "/wechat")
public class WechatRequestController extends BaseController {

	private static final Logger _logger = Logger.getLogger(WechatRequestController.class);

	@Value("${wx.app.token}")
	private String appToken;

	@Value("${wx.app.callbackurl}")
	private String appRedirectUrl;

	@Autowired
	private WechatRequestService wechatRequestService;

	/**   
	 * @Title: notify   
	 * @Description: 微信消息通知回调
	 * @param: @param request
	 * @param: @param response
	 * @param: @throws Exception      
	 * @return: void      
	 * @throws   
	 */
	@RequestMapping(value = "/callback")
	public void notify(HttpServletRequest request, HttpServletResponse response) throws Exception {
		// 微信加密签名
		String signature = request.getParameter("signature");
		// 时间戳
		String timestamp = request.getParameter("timestamp");
		// 随机数
		String nonce = request.getParameter("nonce");
		// 随机字符串
		String echostr = request.getParameter("echostr");

		if (_logger.isDebugEnabled()) {
			_logger.debug(MessageFormat.format("echostr:{0}", echostr));
		}

		ServletOutputStream outputStream = null;
		try {
			response.setContentType("text/html;charset=UTF-8");
			outputStream = response.getOutputStream();
			// 请求校验
			if (SignUtils.checkSignature(appToken, signature, timestamp, nonce)) {
				// 获取当前请求方式
				String method = request.getMethod();
				if ("POST".equals(method.toUpperCase())) {
					// 调用核心服务类接收处理请求
					String respMessage = wechatRequestService.processRequest(request);
					if (null != respMessage) {
						outputStream.write(respMessage.getBytes("UTF-8"));
					}
				} else {
					outputStream.write(echostr.getBytes("UTF-8"));
				}
			}
			outputStream.flush();
		} catch (Exception e) {
			_logger.error("抱歉!系统繁忙,请您稍后再试!!!", e);
		} finally {
			if (outputStream != null) {
				try {
					outputStream.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			outputStream = null;
		}
	}

	/**   
	 * @Title: auth   
	 * @Description: 网页授权回调url
	 * @param: @param code
	 * @param: @param state
	 * @param: @param request
	 * @param: @param response
	 * @param: @throws Exception      
	 * @return: void      
	 * @throws   
	 */
	@RequestMapping(value = "/oauth_callback")
	public void auth(String code, String state, HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		if (code != null) {
			WechatOauth2AccessToken oauth2AcessToken = wechatRequestService.getOauthAccessToken(code);
			if (appRedirectUrl.indexOf('?') > -1) {
				response.sendRedirect(
						appRedirectUrl + "&wechat_openid=" + oauth2AcessToken.getOpenid() + "&wechat_state=" + state);
			} else {
				response.sendRedirect(
						appRedirectUrl + "?wechat_openid=" + oauth2AcessToken.getOpenid() + "&wechat_state=" + state);
			}
		}
	}

	@RequestMapping(value = "/apptest")
	public void appTest(String wechat_openid, String wechat_state, HttpServletRequest request,
			HttpServletResponse response) throws Exception {
		ServletOutputStream outputStream = null;
		try {
			response.setContentType("text/html;charset=UTF-8");
			outputStream = response.getOutputStream();
			outputStream.write(MessageFormat.format("wechat_openid={0}&wechat_state={1}", wechat_openid, wechat_state)
					.getBytes("utf-8"));
			outputStream.flush();
		} catch (Exception e) {
			_logger.error("抱歉!系统繁忙,请您稍后再试!!!", e);
		} finally {
			if (outputStream != null) {
				try {
					outputStream.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			outputStream = null;
		}
	}
}